package org.irri.smta.ui.bean;

import java.io.Serializable;

import javax.faces.model.ListDataModel;
import javax.inject.Inject;
import javax.inject.Named;

import org.irri.smta.common.Constants;
import org.irri.smta.global.GlobalBean;
import org.irri.smta.service.IMessageProviderService;
import org.irri.smta.util.BeanUtils;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;
import org.primefaces.model.SelectableDataModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * An implementation of SelectableDataModel using a list as data.
 */
public abstract class TableBeanBase<T> extends ListDataModel<T> implements
		SelectableDataModel<T>, Serializable {

	private static final long serialVersionUID = 1L;
	private static final Logger LOGGER = LoggerFactory
			.getLogger(TableBeanBase.class);

	@Inject
	@Named("globalBean")
	private GlobalBean globalBean;

	@Inject
	@Named("messageProviderService")
	private IMessageProviderService<String> messageProviderService;

	private String viewName = "";
	private Boolean stateEnabled = false;
	private BeanUtils beanUtils = new BeanUtils();

	public TableBeanBase() {
		super();
	}

	public TableBeanBase(Object data) {
		LOGGER.debug("TableBeanBase(Object data): " + data);
		setWrappedData(data);
	}

	public GlobalBean getGlobalBean() {
		return globalBean;
	}

	public IMessageProviderService<String> getMessageProviderService() {
		return messageProviderService;
	}
	
	public String getViewName() {
		return viewName;
	}

	public void setViewName(String viewName) {
		this.viewName = viewName;
	}

	public Boolean isStateEnabled() {
		return stateEnabled;
	}

	public void setStateEnabled(Boolean stateEnabled) {
		this.stateEnabled = stateEnabled;
	}

	public void preRenderView() {
		if (!beanUtils.validateUser()) {
			beanUtils.navigateToView(Constants.LOGIN_VIEW_NAME);
		} else {
			LOGGER.debug("preRenderView()");
			loadData();
		}
	}

	public void onRowSelect(SelectEvent event) throws Exception {
		LOGGER.debug("onRowSelect(SelectEvent event): " + event);
		if (!stateEnabled) {
			stateEnabled = true;
			refreshView();
		}
	}

	public void onRowSelect(SelectEvent event, Boolean refreshView) throws Exception {
		LOGGER.debug("onRowSelect(SelectEvent event): " + event);
		if (!stateEnabled) {
			stateEnabled = true;
			if (refreshView) {
				refreshView();
			}
		}
	}

	public void onRowUnselect(UnselectEvent event) throws Exception {
		LOGGER.debug("onRowUnselect(UnselectEvent event): " + event);
		stateEnabled = false;
		refreshView();
	}
	
	public Boolean addDisabled() {
		Boolean status = getGlobalBean().canCreate(beanUtils.getSessionUser());
		return !status;
	}

	public Boolean editDisabled() {
		Boolean status = getGlobalBean().canUpdate(beanUtils.getSessionUser());
		if (status && isStateEnabled()) {
			return false;
		}
		return true;
	}

	public Boolean deleteDisabled() {
		Boolean status = getGlobalBean().canDelete(beanUtils.getSessionUser());
		if (status && isStateEnabled()) {
			return false;
		}
		return true;
	}

	public void refreshView() {
		beanUtils.navigateToView(this.viewName);
	}

	public abstract void loadData();

}
